package com.bjl.service.imp;

import com.alibaba.fastjson.JSONObject;
import com.bjl.dao.DealDao;
import com.bjl.dao.UserDao;
import com.bjl.entity.Deal;
import com.bjl.entity.User;
import com.bjl.service.DealService;
import com.bjl.service.LotteryService;
import com.bjl.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import orm.base.Ex.BaseServiceEx;
import orm.dictionary.DealType;
import orm.dictionary.Role;
import orm.dictionary.WinType;
import orm.utils.ChartUtils;
import orm.utils.ExportExcelUtils;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by ashin on 2017/11/22.
 */
@Service
@Scope("prototype")
public class DealServiceImp extends BaseServiceEx implements DealService {

    @Autowired
    DealDao dealDao;

    @Autowired
    ChartUtils chartUtils;

    @Autowired
    UserDao userDao;

    @Autowired
    LotteryService lotteryService;

    @Autowired
    UserService userService;

    DecimalFormat df = new DecimalFormat("######0.00");

    @Override
    public void init() {
        super.init(dealDao);
    }

    @Transactional
    @Override
    public JSONObject recharge(Map map, HttpSession session) throws Exception {
        User user = (User) session.getAttribute("user");
        if (!Role.manageGroup(user.getRole()))
            return this.codeMess(eCode, "抱歉，您的权限不足");
        if (map.get("betAccount") == null) {
            return this.codeMess(eCode, "增加积分不能为空");
        }
        map.put("betInfo", "[" + now() + "] 账户增加 " + map.get("betAccount").toString() + " 积分");
        map.put("orderId", getOrderId());
//        map.put("uId",((User)session.getAttribute("user")).getId());
        map.put("dealType", String.valueOf(DealType.recharge));
        int ret = dealDao.insertp(map);
        if (ret == -1) {
            return this.codeMess(sCode, "增加失败");
        }

        Map dealMap = new HashMap();
        Map userMap = new HashMap();
        userMap.put("id", map.get("uId"));
        User _user = userDao.selectp(userMap);

        List<User> userList = userService.findAllReferrerId(_user);

        //如果上级为空，或者当前用户是测试用户，则直接返回
        if (userList == null || String.valueOf(Role.test).equals(_user.getRole()))
            return this.codeMess(sCode, "增加成功");
        Double rechargeAccount = toDouble(map.get("betAccount").toString());
        double nextRebate = 0d;
        for (User u : userList) {
            double rebate = 0d;
            if (u.getRole().equals(String.valueOf(Role.admin)))
                rebate = rechargeAccount - nextRebate;
            else {
                //向上级返利
                rebate = rechargeAccount * (toDouble(u.getEarningsPercent()) / 100) - nextRebate;
                nextRebate += rebate;
            }
            dealMap.put("uId", u.getId());
            dealMap.put("orderId", getOrderId());
            dealMap.put("dealType", String.valueOf(DealType.recharge));
            dealMap.put("betInfo", "[" + now() + "] " + _user.getRealName() + " 增加" + map.get("betAccount").toString() + ",返利" + df.format(rebate));
            dealMap.put("betAccount", df.format(rebate));
            int _ret = dealDao.insertp(dealMap);
            if (_ret == -1) {
                return this.codeMess(sCode, "增加失败");
            }
        }
        return this.codeMess(sCode, "增加成功");
    }

    public JSONObject query(Map map, HttpSession session) throws Exception {
        User user = (User) session.getAttribute("user");
        if (!Role.manageGroup(user.getRole()))
            return this.codeMess(eCode, "抱歉，您的权限不足");
        return super.query(map);
    }

    /**
     * 核销积分
     *
     * @param map
     * @param session
     * @return
     * @throws Exception
     */
    @Override
    public JSONObject consume(Map map, HttpSession session) throws Exception {
        User user = (User) session.getAttribute("user");
        if (!Role.manageGroup(user.getRole()))
            return this.codeMess(eCode, "抱歉，您的权限不足");
        if (map.get("betAccount") == null) {
            return this.codeMess(eCode, "核销积分不能为空");
        }
        String integral = dealDao.getSingleUserTotal(map);
        if (toDouble(integral.replace(",", "")) < toDouble(map.get("betAccount").toString())) {
            return this.codeMess(eCode, "抱歉，该用户积分不足");
        }
        map.put("betInfo", "[" + now() + "] 账户扣除 " + map.get("betAccount").toString() + "积分");
        map.put("orderId", getOrderId());
        map.put("betAccount", unAbs(toDouble(map.get("betAccount").toString())));
        map.put("dealType", String.valueOf(DealType.consume));
        int ret = dealDao.insertp(map);
        if (ret == -1) {
            return this.codeMess(sCode, "核销失败");
        }
        return this.codeMess(sCode, "核销成功");
    }

    @Override
    public JSONObject bet(Map map, HttpSession session) throws Exception {
        if (map.get("betAccount") == null || map.get("betAccount").toString().equals("0")) {
            return this.codeMess(eCode, "投注积分不能为空或等于0");
        }
        User user = (User)session.getAttribute("user");
        map.put("uId",user.getId());
        String integral = dealDao.getSingleUserTotal(map);
        if (toDouble(integral.replace(",", "")) < toDouble(map.get("betAccount").toString())) {
            return this.codeMess(eCode, "当前积分不足，不能完成投注");
        }
        //查询当前是多少期
        String issue = lotteryService.doGetRoomIssue(map);
        map.put("issue", yymmdd.format(new Date()) + issue);
        map.put("orderId", getOrderId());
        map.put("uId", ((User) session.getAttribute("user")).getId());
        map.put("betAccount", 0 - toDouble(map.get("betAccount").toString()));
        map.put("dealType", String.valueOf(DealType.bet));

        //app发送消息
        Map txtMap = new HashMap();
        txtMap.put("fromUserId", ((User) session.getAttribute("user")).getChart_token());
        txtMap.put("groupId", map.get("roomId"));
        txtMap.put("betInfo", "[ " + kjResult(map.get("betInfo").toString()) + " ] " + Math.abs(toDouble(map.get("betAccount").toString())));
        txtMap.put("extra", "OtherUserBet");
        int ret = dealDao.insertp(map);
        if (ret == -1) {
            return this.codeMess(sCode, "消费失败");
        }
        return this.codeData(txtMap);
    }

    /**
     * 向指定房间发送结果
     *
     * @return
     * @throws Exception
     */
    public boolean sendResult(Map resultMap) throws Exception {
        String[] groupIdArr = {resultMap.get("groupId").toString()};
        return chartUtils.sendTxtMsg(groupIdArr, resultMap.get("fromUserId").toString(), resultMap);
    }

    @Override
    public JSONObject dealAccount(Map map, HttpSession session) throws Exception {
        User user = (User) session.getAttribute("user");
        String role = user.getRole();
        if (String.valueOf(Role.finance).equals(role) || String.valueOf(Role.admin).equals(role)) {
            return this.codeData(dealDao.pagequery(map));
        } else {
            map.put("uId", user.getId());
            return this.codeData(dealDao.pagequery(map));
        }
    }

    @Override
    public JSONObject getSingleUserTotal(Map map, HttpSession session) throws Exception {
        JSONObject jsonObject = new JSONObject();
        User user = (User) session.getAttribute("user");
        map.put("uId", user.getId());
        String integral = dealDao.getSingleUserTotal(map);
        jsonObject.put("integral", integral);
        return this.codeData(jsonObject);
    }

    @Override
    public JSONObject getUserTotal(Map map, HttpSession session) throws Exception {
        User user = (User) session.getAttribute("user");
        String role = user.getRole();
        if (!Role.manageGroup(user.getRole()))
            return this.codeMess(eCode, "抱歉，您的权限不足");
        if (String.valueOf(Role.ow).equals(role)) {
            map.put("leader", user.getId());
        }
        return this.codeData(dealDao.getUserTotal(map));
    }

    @Override
    public void exportUserTotalExcel(Map map, HttpSession session, HttpServletResponse response) throws Exception {
        User user = (User) session.getAttribute("user");
        String role = user.getRole();
        if (!Role.manageGroup(role))
            response.getWriter().write("抱歉，您的权限不足");
        if (String.valueOf(Role.ow).equals(role)) {
            map.put("leader", user.getId());
        }
        List<Map> userTotalList = dealDao.getUserTotal(map);
        Map<String,List<Object>> _map = formList(userTotalList);
        ExportExcelUtils.exportWithHeadExcel("用户积分出入总额", _map.get("head").toArray(new String[]{}), _map.get("body"), response);
    }

    @Override
    public JSONObject getSingleUserTotalByAdmin(Map map, HttpSession session) throws Exception {
        JSONObject jsonObject = new JSONObject();
        User user = (User) session.getAttribute("user");
        if (!Role.manageGroup(user.getRole()))
            return this.codeMess(eCode, "抱歉，您的权限不足");
        String integral = dealDao.getSingleUserTotal(map);
        jsonObject.put("integral", integral);
        return this.codeData(jsonObject);
    }

    @Override
    public JSONObject queryUserCountByPerHour(Map map, HttpSession session) throws Exception {
        User user = (User) session.getAttribute("user");
        String role = user.getRole();
        if (!Role.manageGroup(role))
            return this.codeMess(eCode, "抱歉，您的权限不足");
        if (String.valueOf(Role.ow).equals(role)) {
            map.put("leader", user.getId());
        }
        return this.codeData(dealDao.queryUserCountByPerHour(map));
    }

    @Override
    public void exportUserCountByPerHour(Map map, HttpSession session, HttpServletResponse response) throws Exception {
        User user = (User) session.getAttribute("user");
        String role = user.getRole();
        if (!Role.manageGroup(role))
            response.getWriter().write("抱歉，您的权限不足");
        if (String.valueOf(Role.ow).equals(role)) {
            map.put("leader", user.getId());
        }
        List<Map> userCountByPerHour = dealDao.queryUserCountByPerHour(map);
        Map<String,List<Object>> _map = formList(userCountByPerHour);
        ExportExcelUtils.exportWithHeadExcel("在线人数",  _map.get("head").toArray(new String[]{}), _map.get("body"), response);
    }

    @Override
    public JSONObject queryUserIntegralRoom(Map map, HttpSession session) throws Exception {
        User user = (User) session.getAttribute("user");
        map.put("uId", user.getId());
        return this.codeData(dealDao.queryUserIntegralRoom(map));
    }

    @Override
    public JSONObject queryAllIntegralRoom(Map map, HttpSession session) throws Exception {
        return this.codeData(dealDao.queryAllIntegralRoom(map));
    }

    @Override
    public JSONObject querySingleIssueAccount(Map map, HttpSession session) throws Exception {
        String issue = lotteryService.doGetRoomIssue(map);
        map.put("issue", yymmdd.format(new Date()) + issue);
        Map backMap = dealDao.querySingleIssueAccount(map);
        backMap.put("issue", issue);
        return this.codeData(backMap);
    }

    @Override
    public JSONObject checkIsWin(Map map, HttpSession session) throws Exception {
        User user = (User) session.getAttribute("user");
        map.put("uId", user.getId());
        map.put("isWin",String.valueOf(WinType.win));
        Deal deal = dealDao.checkIsWin(map);
        if (deal == null) {
            deal = new Deal();
            deal.setIsWin(String.valueOf(WinType.nowWin));
            return this.codeData(deal);
        }
//        String isWin = deal.getIsWin();
//        if (isWin.equals(String.valueOf(WinType.nowWin)))
//            return this.codeMess(sCode, "本期未中奖");
//        else if (isWin.equals(String.valueOf(WinType.win)))
//            return this.codeData(deal);
//        else
//            return this.codeMess(sCode, "本期未开奖");
        return this.codeData(deal);
    }

    @Override
    public JSONObject queryAllDataInfo(Map map, HttpSession session) throws Exception {
        User user = (User) session.getAttribute("user");
        if(!String.valueOf(Role.admin).equals(user.getRole())){
            return this.codeMess(eCode,"抱歉您的权限不够");
        }
        map = getStatisticsDate(map);
        List<Map> mapList = dealDao.queryAllDataInfo(map);
        return this.codeData(mapList);
    }

    @Override
    public JSONObject queryRoomsDataInfo(Map map, HttpSession session) throws Exception {
        User user = (User) session.getAttribute("user");
        if(!String.valueOf(Role.ow).equals(user.getRole()) && !String.valueOf(Role.admin).equals(user.getRole())){
            return this.codeMess(eCode,"抱歉您的权限不够");
        }
        if(String.valueOf(Role.ow).equals(user.getRole()))
            map.put("owner",user.getId());
        map = getStatisticsDate(map);
        List<String> userIdList = userService.findDownwardUserId(user);
        map.put("downWardUsers", StringUtils.strip(userIdList.toString(),"[]"));
        List<Map> mapList = dealDao.queryRoomsDataInfo(map);
        return this.codeData(mapList);
    }

    @Override
    public JSONObject queryUserDataInfo(Map map, HttpSession session) throws Exception {
        User user = (User) session.getAttribute("user");
        if(!Role.manageGroup(user.getRole())){
            return this.codeMess(eCode,"抱歉您的权限不够");
        }

        map = getStatisticsDate(map);
        List<String> userIdList = userService.findDownwardUserId(user);
        map.put("referrerIds", StringUtils.strip(userIdList.toString(),"[]"));
        List<Map> mapList = dealDao.queryUserDataInfo(map);
        return this.codeData(mapList);
    }

    @Override
    public void exportAllDataInfo(Map map, HttpSession session, HttpServletResponse response) throws Exception {
        User user = (User) session.getAttribute("user");
        if(!String.valueOf(Role.admin).equals(user.getRole())){
            response.getWriter().write("抱歉，您的权限不足");
        }
        map = getStatisticsDate(map);
        List<Map> mapList = dealDao.queryAllDataInfo(map);
        Map<String,List<Object>> _map = formList(mapList);
//        ExportExcelUtils.exportWithHeadExcel("总表概览", new String[]{"用户总赢分", "统计时间","日期","房间总人数","上分总数","核销总人数","平台总赢分","今日新增人数","房间总数","上分总人数","核销总积分"}, formList(mapList), response);
        ExportExcelUtils.exportWithHeadExcel("总表概览", _map.get("head").toArray(new String[]{}), _map.get("body"), response);
    }

    @Override
    public void exportRoomsDataInfo(Map map, HttpSession session, HttpServletResponse response) throws Exception {
        User user = (User) session.getAttribute("user");
        if(!String.valueOf(Role.ow).equals(user.getRole()) && !String.valueOf(Role.admin).equals(user.getRole())){
            response.getWriter().write("抱歉，您的权限不足");
        }
        if(String.valueOf(Role.ow).equals(user.getRole()))
            map.put("owner",user.getId());
        map = getStatisticsDate(map);
        List<String> userIdList = userService.findDownwardUserId(user);
        map.put("downWardUsers", StringUtils.strip(userIdList.toString(),"[]"));
        List<Map> mapList = dealDao.queryRoomsDataInfo(map);
        Map<String,List<Object>> _map = formList(mapList);
        ExportExcelUtils.exportWithHeadExcel("房间概览", _map.get("head").toArray(new String[]{}), _map.get("body"), response);
    }

    @Override
    public void exportUserDataInfo(Map map, HttpSession session, HttpServletResponse response) throws Exception {
        User user = (User) session.getAttribute("user");
        if(!Role.manageGroup(user.getRole())){
            response.getWriter().write("抱歉，您的权限不足");
        }

        map = getStatisticsDate(map);
        List<String> userIdList = userService.findDownwardUserId(user);
        map.put("referrerIds", StringUtils.strip(userIdList.toString(),"[]"));
        List<Map> mapList = dealDao.queryUserDataInfo(map);
        Map<String,List<Object>> _map = formList(mapList);
        ExportExcelUtils.exportWithHeadExcel("用户概览", _map.get("head").toArray(new String[]{}), _map.get("body"), response);
    }

    private Map getStatisticsDate(Map map) throws Exception{
        String startTime = "";
        String endTime = "";
        if(map.get("startTime") != null && map.get("endTime") != null){
            startTime = map.get("startTime").toString();
            endTime = map.get("endTime").toString();
            map.put("statisticsDate",startTime + " 至 " + endTime);
        }else if(map.get("startTime") != null && map.get("endTime") == null){
            startTime = map.get("startTime").toString();
            map.put("statisticsDate",startTime + " 至 ?");
        }else if(map.get("startTime") == null && map.get("endTime") != null){
            endTime = map.get("endTime").toString();
            map.put("statisticsDate","? 至 " + endTime);
        }else{
            map.put("statisticsDate",s_d_f.format(new Date()));
        }
        return map;
    }

}

